package com.fadadianqi.logistics.customer.service;

import com.fadadianqi.cache.Cache;
import com.fadadianqi.cache.CacheFactory;
import com.fadadianqi.commons.PrimaryKeyCreator;
import com.fadadianqi.logistics.customer.dao.CustomerDAO;
import com.fadadianqi.logistics.customer.dao.TownDAO;
import com.fadadianqi.logistics.customer.dao.VillageDAO;
import com.fadadianqi.logistics.customer.model.Customer;
import com.fadadianqi.logistics.customer.model.Town;
import com.fadadianqi.logistics.customer.model.Village;
import com.fadadianqi.search.IndexObjectBufferPool;
import com.yeqiangwei.commons.util.Pagination;
import com.yeqiangwei.commons.util.StringHelper;
import com.yeqiangwei.commons.util.ValidatorHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("customerService")
public class CustomerService {

    private Cache cache = CacheFactory.getDefault();

    /**
     * @param customer
     */
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Throwable.class)
    public void saveCustomer(Customer customer) {
        String name = customer.getName();
        customer.setPinyin(StringHelper.toPinyin(customer.getName()));
        String villageId = customer.getVillageId();
        if (ValidatorHelper.isEmpty(customer.getId())) {
            Customer _customer = customerDAO.getByNameAndVillageId(name, villageId);
            if (_customer != null) {
                customer.setId(_customer.getId());
                customer.setMemo(customer.getMemo() + _customer.getMemo());
            }
            customer.setIndexed(Boolean.FALSE);
            customer.setId(PrimaryKeyCreator.create());
            customerDAO.create(customer);
        } else {
            customerDAO.update(customer);
        }
        Village village = getVillageById(villageId);
        if (village != null) {
            saveVillage(village);
        }
        IndexObjectBufferPool.add(customer);
        cache.set("customer_" + customer.getId(), customer);
    }

    public Customer getById(String id) {
        if (ValidatorHelper.isEmpty(id)) {
            return null;
        }
        Customer c = (Customer) cache.get("customer_" + id);
        if (c == null) {
            c = customerDAO.getById(id);
            cache.set("customer_" + id, c);
        }
        return c;
    }

    public void updateCustomerIndexed(Customer c) {
        customerDAO.update(c);
        cache.set("customer_" + c.getId(), c);
    }

    /**
     * @param customerName
     * @param villageId
     * @return
     */
    public Customer getByNameAndVillageId(String customerName, String villageId) {
        Customer customer = customerDAO.getByNameAndVillageId(customerName, villageId);
        return customer;
    }

    public int countValliage() {
        // TODO Auto-generated method stub
        return 0;
    }

    /**
     * @param townId
     * @return
     */
    public List<Village> findAllVillage(String townId) {
        List<Village> list = null;
        if (ValidatorHelper.isEmpty(townId)) {
            list = villageDAO.findAll();
        } else {
            list = villageDAO.findByTownId(townId);
        }
        return list;
    }

    public void saveVillage(Village village) {
        village.setPinyin(StringHelper.toPinyin(village.getName()));
        if (ValidatorHelper.isEmpty(village.getId())) {
            village.setCount(0);
            village.setId(PrimaryKeyCreator.create());
            villageDAO.create(village);
            IndexObjectBufferPool.add(village);
        } else {
            village.setCount(customerDAO.countByVillageId(village.getId()));
            villageDAO.update(village);
            customerDAO.updateTownIdByVillageId(village.getTownId(), village.getId());
        }
        IndexObjectBufferPool.add(village);
        cache.del("village_" + village.getId());
    }

    public Village getVillageByName(String name) {
        if (ValidatorHelper.isEmpty(name)) {
            return null;
        }
        return villageDAO.getByName(name);
    }

    public Village getVillageById(String id) {
        if (ValidatorHelper.isEmpty(id)) {
            return null;
        }
        Village _v = (Village) cache.get("village_" + id);
        if (_v == null) {
            _v = villageDAO.getById(id);
            cache.set("village_" + id, _v);
        }
        return _v;
    }

    public List<Town> findAllTown() {
        return townDAO.findAll();
    }

    public void saveTown(Town town) {
        if (ValidatorHelper.isEmpty(town)) {
            return;
        }
        town.setPinyin(StringHelper.toPinyin(town.getName()));
        if (ValidatorHelper.isEmpty(town.getId())) {
            Town _town = townDAO.getByName(town.getName());
            if (_town == null) {
                town.setId(PrimaryKeyCreator.create());
                townDAO.create(town);
            } else {
                town.setId(_town.getId());
                townDAO.update(town);
            }
        } else {
            townDAO.update(town);
        }
        IndexObjectBufferPool.add(town);
        cache.del("town_" + town.getId());
    }

    public Town getTownById(String townId) {
        Town t = (Town) cache.get("town_" + townId);
        if (t == null) {
            t = townDAO.getById(townId);
            cache.set("town_" + townId, t);
        }
        return t;
    }

    public Town getTownByName(String name) {
        return townDAO.getByName(name);
    }

    public List<Customer> findAll(Pagination pagination) {
        pagination.setOrderList(new Pagination.Order[]{
                Pagination.getNewOrder(Customer.PROP_ID, !Pagination.Order.ASCENDING)
        });
        return customerDAO.findAll(pagination);
    }

    public List<Customer> findAllByTownId(String townId, Pagination pagination) {
        pagination.setOrderList(new Pagination.Order[]{
                Pagination.getNewOrder(Customer.PROP_ID, !Pagination.Order.ASCENDING)
        });
        return customerDAO.findAllByTownId(townId, pagination);
    }

    public List<Customer> findAllByVillageId(String villageId,
                                             Pagination pagination) {
        pagination.setOrderList(new Pagination.Order[]{
                Pagination.getNewOrder(Customer.PROP_ID, !Pagination.Order.ASCENDING)
        });
        return customerDAO.findAllByVillageId(villageId, pagination);
    }

    public List<Customer> findAllNotIndexed(Pagination pagination) {
        pagination.setOrderList(new Pagination.Order[]{
                Pagination.getNewOrder(Customer.PROP_ID, !Pagination.Order.ASCENDING)
        });
        return customerDAO.findAllNotIndexed(pagination);
    }

    public int countAllNotIndexed() {
        return customerDAO.countAllNotIndexed();
    }

    public Integer countAll() {
        return customerDAO.countAll();
    }

    public Integer countByVillageId(String villageId) {
        return customerDAO.countByVillageId(villageId);
    }

    public int countByTownId(String townId) {
        return customerDAO.countByTownId(townId);
    }


    @Autowired
    private VillageDAO villageDAO;

    @Autowired
    private TownDAO townDAO;

    @Autowired
    private CustomerDAO customerDAO;

}
